有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java方法next()中的NoTouchElementException

方法removeDuplicate(ArrayList<Card> l)的目的是基于类Card中的属性card_value删除重复的对象,然后将它们添加到ArrayList并返回arr

但是我的程序返回一个错误:NoSuchElementException

dum.add((Card) it.next());

我不知道这里发生了什么,因为我打印出了next()方法返回的对象,它打印得非常完美

有人请告诉我为什么我在下面的实现中出错:

private ArrayList<Card> removeDuplicate(ArrayList<Card> l){
    int end = l.size();
    Set<Card> set = new HashSet<>();

    for(int i = 0; i < end; i++){
        set.add(l.get(i));
    }
    ArrayList<Card> dummy = new ArrayList<>();
    Iterator it = set.iterator();
    while(it.hasNext()){
        System.out.println(it.next());
        dummy.add((Card) it.next());
    }

    return dummy;
}

以下是覆盖方法:

@Override
    public int hashCode() {
        int hash = 5;
        hash = 97 * hash + this.card_value;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this){
            return true;
        }
        if (!(obj instanceof Card)){
            return false;
        }
        Card other = (Card) obj;
        return (this.card_value == other.card_value);
    }

共 (3) 个答案

  1. # 1 楼答案

    你打了两次电话next()获取迭代器中的下一个元素,但只检查第一个元素之前的hasNext()

    改变

    while(it.hasNext()){
        System.out.println(it.next());
        dummy.add((Card) it.next());
    }
    

    while(it.hasNext()){
        Card nextCard = (Card) it.next();
        System.out.println(nextCard);
        dummy.add(nextCard);
    }
    
  2. # 2 楼答案

    Here您可以从java^{}中看到^{}方法的源代码。它看起来像这样:

    public E next() {
        checkForComodification();
        try {
            int i = cursor;
            E next = get(i);
            lastRet = i;
            cursor = i + 1;
            return next;
        } catch (IndexOutOfBoundsException e) {
            checkForComodification();
            throw new NoSuchElementException();
        }
    }
    

    如您所见,如果您不在数组中,将抛出一个^{}。因此,通过使用hasNext()调用next()两次而不在每次调用之前检查元素是否仍然可用,将具有您描述的行为

    你的while()应该替换为:

    while(it.hasNext()) {
        dummy.add((Card) it.next());
    }
    

    但是,如果您真的希望打印出来,只需将其更改为:

    while (it.hasNext()) {
        Card card = (Card)it.next();
        System.out.println(card);
        dummy.add(card);
    }
    

    第二种方法是在方法或循环中需要多次使用对象(如果调用的方法可能很昂贵)时更好的方法

  3. # 3 楼答案

    因为next()每次都在指针上移动,所以当你打印出来时,它会打印最后一个指针,然后在打印完后再次移动